/********************************************************************************/
/********************************************************************************/

#ifndef TPM2_COMMAND_H
#define TPM2_COMMAND_H

enum dtype_tpm2_input{
	TYPE(TPM2_IN)=0x2110,
	TYPE(TPM2_OUT)=0x2120,
	TYPE(TPM2_HEAD)=0x2130,
	TYPE(TPM2_UTILS)=0x2140
};

enum subtype_tpm2_utils{
	SUBTYPE(TPM2_UTILS,INPUT)=0x01,
	SUBTYPE(TPM2_UTILS,OUTPUT),
	SUBTYPE(TPM2_UTILS,PIK_CERT)
};

enum subtype_tpm2_in{
	SUBTYPE(TPM2_IN,GetRandom)=0x7B010000,
	SUBTYPE(TPM2_IN,PCR_Read)=0x7E010000,
	SUBTYPE(TPM2_IN,PCR_Extend)=0x82010000,
	SUBTYPE(TPM2_IN,PCR_SetAuthValue)=0x83010000,
	SUBTYPE(TPM2_IN,CreatePrimary)=0x31010000,
	SUBTYPE(TPM2_IN,Create)=0x53010000,
	SUBTYPE(TPM2_IN,Load)=0x57010000
};


enum subtype_tpm2_out{
	SUBTYPE(TPM2_OUT,GetRandom)=0x7B010000,
	SUBTYPE(TPM2_OUT,PCR_Read)=0x7E010000,
	SUBTYPE(TPM2_OUT,PCR_Extend)=0x82010000,
	SUBTYPE(TPM2_OUT,PCR_SetAuthValue)=0x83010000,
    SUBTYPE(TPM2_OUT,CreatePrimary)=0x31010000,
    SUBTYPE(TPM2_OUT,Create)=0x53010000,
    SUBTYPE(TPM2_OUT,Load)=0x57010000
};
//#include "tcm_types.h"

typedef struct tpm2_in_GetRandom{
	UINT16 tag;
	int    commandSize;
	int    commandCode;
	UINT16  bytesRequested;
}__attribute__((packed)) RECORD(TPM2_IN,GetRandom);

typedef struct tpm2_out_GetRandom{
	UINT16 tag;
	int    responseSize;
	int    responseCode;
	TPM2B_DIGEST randomBytes;
}__attribute__((packed)) RECORD(TPM2_OUT,GetRandom);

typedef struct tpm2_in_PCR_Extend{
	UINT16 tag;
	int    commandSize;
	int    commandCode;
	UINT32 pcrHandle;
	TPML_DIGEST digests;	
}__attribute__((packed)) RECORD(TPM2_IN,PCR_Extend);

typedef struct tpm2_out_PCR_Extend{
	UINT16 tag;
	int    responseSize;
	int    responseCode;
}__attribute__((packed)) RECORD(TPM2_OUT,PCR_Extend);

typedef struct tpm2_in_PCR_Read{
	UINT16 tag;
	int    commandSize;
	int    commandCode;
	TPML_PCR_SELECTION  pcrSelectionIn;	
}__attribute__((packed)) RECORD(TPM2_IN,PCR_Read);

typedef struct tpm2_out_PCR_Read{
	UINT16 tag;
	int    responseSize;
	int    responseCode;
	int    pcrUpdateCounter;
	TPML_PCR_SELECTION  pcrSelectionOut;
	TPML_DIGEST pcrValues;	 
}__attribute__((packed)) RECORD(TPM2_OUT,PCR_Read);

typedef struct tpm2_utils_input
{
    int param_num;
    BYTE * params;
}__attribute__((packed)) RECORD(TPM2_UTILS,INPUT);

typedef struct tpm2_utils_output
{
    int param_num;
    BYTE * params;
}__attribute__((packed)) RECORD(TPM2_UTILS,OUTPUT);

typedef struct tpm2_in_CreatePrimary
{
	UINT16 tag;
	int commandSize;
	int commandCode;
	TPMI_RH_HIERARCHY primaryHandle; // TPM_RH_ENDORSEMENT, TPM_RH_OWNER, TPM_RH_PLATFORM+{PP}, or TPM_RH_NULL.	Auth Index: 1; Auth Role: USER
	// /*查看TCG_TPM2_Part1 27.3 : Sensitive Values . */
	TPM2B_SENSITIVE_CREATE inSensitive;
	// /*查看TCG_TPM2_Part1 27.2 : Public Area Template . */
	TPM2B_PUBLIC inPublic;
	// 将包含在此对象的创建数据中的数据，以提供此对象和一些对象所有者数据之间的永久、可核查的联系
	TPM2B_DATA outsideInfo;
	// /*查看TCG_TPM2_Part1 27.4 : creationPCR . */
	TPML_PCR_SELECTION creationPCR;
} __attribute__((packed)) RECORD(TPM2_IN, CreatePrimary);

typedef struct tpm2_out_CreatePrimary
{
	UINT16 tag;
	int responseSize;
	int responseCode;
	UINT32 objectHandle;
	TPM2B_PUBLIC outPublic;
	TPM2B_CREATION_DATA creationData;
	TPM2B_DIGEST creationHash;
	TPMT_TK_CREATION creationTicket;
	TPM2B_NAME name;
} __attribute__((packed)) RECORD(TPM2_OUT, CreatePrimary);

typedef struct tpm2_in_create
{
	UINT16 tag;
	int commandSize;
	int commandCode;
	TPMI_DH_OBJECT parentHandle;
	TPM2B_SENSITIVE_CREATE inSensitive;
	TPM2B_PUBLIC inPublic;
	TPM2B_DATA outsideInfo;
	TPML_PCR_SELECTION creationPCR;
} __attribute__((packed)) RECORD(TPM2_IN, Create);

typedef struct tpm2_out_create
{
	UINT16 tag;
	int responseSize;
	int responseCode;
	TPM2B_PRIVATE outPrivate;
	TPM2B_PUBLIC outPublic;
	TPM2B_CREATION_DATA creationData;
	TPM2B_DIGEST creationHash;
	TPMT_TK_CREATION creationTicket;
} __attribute__((packed)) RECORD(TPM2_OUT, Create);


typedef struct tpm2_in_load
{
	UINT16 tag;
	int commandSize;
	int commandCode;
	TPMI_DH_OBJECT parentHandle;
	TPM2B_PRIVATE inPrivate;
	TPM2B_PUBLIC inPublic;
} __attribute__((packed)) RECORD(TPM2_IN, Load);

typedef struct tpm2_out_load
{
	UINT16 tag;
	int responseSize;
	int responseCode;
	TPM_HANDLE objectHandle;
	TPM2B_NAME name;
} __attribute__((packed)) RECORD(TPM2_OUT, Load);

#endif
